using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;

namespace axCommerce.Data
{
	[DataObject]
	[Serializable]
	public partial class CustomerInfo
	{
		#region Constants

		private const string TableName = "[dbo].[CustomerInfo]";

		#endregion

		#region Properties

		public int? CustomerInfoId { get; set; }
		public int? AccountId { get; set; }
		public int? CityId { get; set; }
		public int? PaymentTypeId { get; set; }
		public string FirstName { get; set; }
		public string MiddleName { get; set; }
		public string LastName { get; set; }
		public int? PostIndex { get; set; }
		public string PostAddress { get; set; }
		public string Phone { get; set; }
		public int? Icq { get; set; }
		public string Skype { get; set; }
		public string Email { get; set; }
		public DateTime? CreatedDate { get; set; }
		public DateTime? LastModifiedDate { get; set; }

		#endregion

		#region Methods

		#region Mapping Methods

		protected void MapTo(DataSet ds)
		{
			if (ds == null)
				ds = new DataSet();

			if (ds.Tables[TableName] == null)
				ds.Tables.Add(TableName);

			ds.Tables[TableName].Columns.Add("CustomerInfoId", typeof (Int32));
			ds.Tables[TableName].Columns.Add("AccountId", typeof (Int32));
			ds.Tables[TableName].Columns.Add("CityId", typeof (Int32));
			ds.Tables[TableName].Columns.Add("PaymentTypeId", typeof (Int32));
			ds.Tables[TableName].Columns.Add("FirstName", typeof (String));
			ds.Tables[TableName].Columns.Add("MiddleName", typeof (String));
			ds.Tables[TableName].Columns.Add("LastName", typeof (String));
			ds.Tables[TableName].Columns.Add("PostIndex", typeof (Int32));
			ds.Tables[TableName].Columns.Add("PostAddress", typeof (String));
			ds.Tables[TableName].Columns.Add("Phone", typeof (String));
			ds.Tables[TableName].Columns.Add("Icq", typeof (Int32));
			ds.Tables[TableName].Columns.Add("Skype", typeof (String));
			ds.Tables[TableName].Columns.Add("Email", typeof (String));
			ds.Tables[TableName].Columns.Add("CreatedDate", typeof (DateTime));
			ds.Tables[TableName].Columns.Add("LastModifiedDate", typeof (DateTime));

			DataRow dr = ds.Tables[TableName].NewRow();

			dr["CustomerInfoId"] = CustomerInfoId ?? (object) DBNull.Value;
			dr["AccountId"] = AccountId ?? (object) DBNull.Value;
			dr["CityId"] = CityId ?? (object) DBNull.Value;
			dr["PaymentTypeId"] = PaymentTypeId ?? (object) DBNull.Value;
			dr["FirstName"] = FirstName ?? (object) DBNull.Value;
			dr["MiddleName"] = MiddleName ?? (object) DBNull.Value;
			dr["LastName"] = LastName ?? (object) DBNull.Value;
			dr["PostIndex"] = PostIndex ?? (object) DBNull.Value;
			dr["PostAddress"] = PostAddress ?? (object) DBNull.Value;
			dr["Phone"] = Phone ?? (object) DBNull.Value;
			dr["Icq"] = Icq ?? (object) DBNull.Value;
			dr["Skype"] = Skype ?? (object) DBNull.Value;
			dr["Email"] = Email ?? (object) DBNull.Value;
			dr["CreatedDate"] = CreatedDate ?? (object) DBNull.Value;
			dr["LastModifiedDate"] = LastModifiedDate ?? (object) DBNull.Value;

			ds.Tables[TableName].Rows.Add(dr);
		}

		protected void MapFrom(DataRow dr)
		{
			CustomerInfoId = dr["CustomerInfoId"] != DBNull.Value ? Convert.ToInt32(dr["CustomerInfoId"]) : CustomerInfoId = null;
			AccountId = dr["AccountId"] != DBNull.Value ? Convert.ToInt32(dr["AccountId"]) : AccountId = null;
			CityId = dr["CityId"] != DBNull.Value ? Convert.ToInt32(dr["CityId"]) : CityId = null;
			PaymentTypeId = dr["PaymentTypeId"] != DBNull.Value ? Convert.ToInt32(dr["PaymentTypeId"]) : PaymentTypeId = null;
			FirstName = dr["FirstName"] != DBNull.Value ? Convert.ToString(dr["FirstName"]) : FirstName = null;
			MiddleName = dr["MiddleName"] != DBNull.Value ? Convert.ToString(dr["MiddleName"]) : MiddleName = null;
			LastName = dr["LastName"] != DBNull.Value ? Convert.ToString(dr["LastName"]) : LastName = null;
			PostIndex = dr["PostIndex"] != DBNull.Value ? Convert.ToInt32(dr["PostIndex"]) : PostIndex = null;
			PostAddress = dr["PostAddress"] != DBNull.Value ? Convert.ToString(dr["PostAddress"]) : PostAddress = null;
			Phone = dr["Phone"] != DBNull.Value ? Convert.ToString(dr["Phone"]) : Phone = null;
			Icq = dr["Icq"] != DBNull.Value ? Convert.ToInt32(dr["Icq"]) : Icq = null;
			Skype = dr["Skype"] != DBNull.Value ? Convert.ToString(dr["Skype"]) : Skype = null;
			Email = dr["Email"] != DBNull.Value ? Convert.ToString(dr["Email"]) : Email = null;
			CreatedDate = dr["CreatedDate"] != DBNull.Value ? Convert.ToDateTime(dr["CreatedDate"]) : CreatedDate = null;
			LastModifiedDate = dr["LastModifiedDate"] != DBNull.Value
			                   	? Convert.ToDateTime(dr["LastModifiedDate"])
			                   	: LastModifiedDate = null;

			FillAccountInfo();
		}

		private static List<CustomerInfo> MapFrom(DataSet ds)
		{
			// Initialise Collection.
			List<CustomerInfo> objects = new List<CustomerInfo>();

			// Validation.
			if (ds == null)
				throw new ApplicationException("Cannot map to dataset null.");
			
			if (ds.Tables[TableName].Rows.Count == 0)
				return objects;

			if (ds.Tables[TableName] == null)
				throw new ApplicationException("Cannot find table [dbo].[CustomerInfo] in DataSet.");

			if (ds.Tables[TableName].Rows.Count < 1)
				throw new ApplicationException("Table [dbo].[CustomerInfo] is empty.");

			// Map DataSet to Instance.
			foreach (DataRow dr in ds.Tables[TableName].Rows)
			{
				var instance = new CustomerInfo();
				instance.MapFrom(dr);
				objects.Add(instance);
			}

			// Return collection.
			return objects;
		}

		#endregion

		#region CRUD Methods

		internal static CustomerInfo Get(Int32 customerInfoId)
		{
			CustomerInfo instance = new CustomerInfo();

			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_SELECT";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, customerInfoId))
			{
				using (DataSet ds = db.ExecuteDataSet(dbCommand))
				{
					if (ds == null || ds.Tables[0].Rows.Count == 0)
						throw new ApplicationException(String.Format("Could not get CustomerInfo ID:{0} from Database.", customerInfoId));
					// Return results.
					ds.Tables[0].TableName = TableName;

					instance.MapFrom(ds.Tables[0].Rows[0]);
				}
			}
			return instance;
		}

		#region INSERT

		private void Insert(Int32? accountId, Int32? cityId, Int32? paymentTypeId, String firstName, String middleName,
		                   String lastName, Int32? postIndex, String postAddress, String phone, Int32? icq, String skype,
		                   String email, DateTime? createdDate, DateTime? lastModifiedDate, DbTransaction transaction)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_INSERT";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, accountId, cityId, paymentTypeId, firstName, middleName, lastName, postIndex, postAddress, phone, icq, skype, email, createdDate, lastModifiedDate))
			{
				CustomerInfoId =
					Convert.ToInt32(transaction == null ? db.ExecuteScalar(dbCommand) : db.ExecuteScalar(dbCommand, transaction));
			}
		}

		private void Insert(Int32? accountId, Int32? cityId, Int32? paymentTypeId, String firstName, String middleName,
		                   String lastName, Int32? postIndex, String postAddress, String phone, Int32? icq, String skype,
		                   String email, DateTime? createdDate, DateTime? lastModifiedDate)
		{
			Insert(accountId, cityId, paymentTypeId, firstName, middleName, lastName, postIndex, postAddress, phone, icq, skype,
			       email, createdDate, lastModifiedDate, null);
		}

		/// <summary>
		/// Insert current CustomerInfo to database.
		/// </summary>
		/// <param name="transaction">optional SQL Transaction</param>
		private void Insert(DbTransaction transaction = null)
		{
			Insert(AccountId, CityId, PaymentTypeId, FirstName, MiddleName, LastName, PostIndex, PostAddress, Phone, Icq, Skype,
			       Email, CreatedDate, LastModifiedDate, transaction);
		}

		#endregion

		#region UPDATE

		private static void Update(Int32? customerInfoId, Int32? accountId, Int32? cityId, Int32? paymentTypeId,
		                          String firstName, String middleName, String lastName, Int32? postIndex, String postAddress,
		                          String phone, Int32? icq, String skype, String email, DateTime? createdDate,
		                          DateTime? lastModifiedDate, DbTransaction transaction = null)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_UPDATE";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand))
			{
				db.DiscoverParameters(dbCommand);
				dbCommand.Parameters["@customerInfoId"].Value = customerInfoId;
				dbCommand.Parameters["@accountId"].Value = accountId;
				dbCommand.Parameters["@cityId"].Value = cityId;
				dbCommand.Parameters["@paymentTypeId"].Value = paymentTypeId;
				dbCommand.Parameters["@firstName"].Value = firstName;
				dbCommand.Parameters["@middleName"].Value = middleName;
				dbCommand.Parameters["@lastName"].Value = lastName;
				dbCommand.Parameters["@postIndex"].Value = postIndex;
				dbCommand.Parameters["@postAddress"].Value = postAddress;
				dbCommand.Parameters["@phone"].Value = phone;
				dbCommand.Parameters["@icq"].Value = icq;
				dbCommand.Parameters["@skype"].Value = skype;
				dbCommand.Parameters["@email"].Value = email;
				dbCommand.Parameters["@createdDate"].Value = createdDate;
				dbCommand.Parameters["@lastModifiedDate"].Value = lastModifiedDate;

				if (transaction == null)
					db.ExecuteNonQuery(dbCommand);
				else
					db.ExecuteNonQuery(dbCommand, transaction);
			}
		}

		private static void Update(CustomerInfo customerInfo)
		{
			customerInfo.Update();
		}

		private static void Update(CustomerInfo customerInfo, DbTransaction transaction)
		{
			customerInfo.Update(transaction);
		}

		/// <summary>
		/// Updates changes to the database.
		/// </summary>
		/// <param name="transaction">optional SQL Transaction</param>
		private void Update(DbTransaction transaction = null)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_UPDATE";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand))
			{
				db.DiscoverParameters(dbCommand);
				dbCommand.Parameters["@customerInfoId"].SourceColumn = "CustomerInfoId";
				dbCommand.Parameters["@accountId"].SourceColumn = "AccountId";
				dbCommand.Parameters["@cityId"].SourceColumn = "CityId";
				dbCommand.Parameters["@paymentTypeId"].SourceColumn = "PaymentTypeId";
				dbCommand.Parameters["@firstName"].SourceColumn = "FirstName";
				dbCommand.Parameters["@middleName"].SourceColumn = "MiddleName";
				dbCommand.Parameters["@lastName"].SourceColumn = "LastName";
				dbCommand.Parameters["@postIndex"].SourceColumn = "PostIndex";
				dbCommand.Parameters["@postAddress"].SourceColumn = "PostAddress";
				dbCommand.Parameters["@phone"].SourceColumn = "Phone";
				dbCommand.Parameters["@icq"].SourceColumn = "Icq";
				dbCommand.Parameters["@skype"].SourceColumn = "Skype";
				dbCommand.Parameters["@email"].SourceColumn = "Email";
				dbCommand.Parameters["@createdDate"].SourceColumn = "CreatedDate";
				dbCommand.Parameters["@lastModifiedDate"].SourceColumn = "LastModifiedDate";

				using (DataSet ds = new DataSet())
				{
					MapTo(ds);
					ds.AcceptChanges();
					ds.Tables[0].Rows[0].SetModified();
					if (transaction == null)
						db.UpdateDataSet(ds, TableName, null, dbCommand, null, UpdateBehavior.Standard);
					else
						db.UpdateDataSet(ds, TableName, null, dbCommand, null, transaction);
				}
			}
		}

		#endregion

		#region DELETE

		private static void Delete(Int32? customerInfoId, DbTransaction transaction)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_DELETE";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, customerInfoId))
			{
				if (transaction != null)
				{
					db.ExecuteNonQuery(dbCommand, transaction);
				}
				else
				{
					db.ExecuteNonQuery(dbCommand);
				}
			}
		}

		/// <summary>
		/// Delete current CustomerInfo from database.
		/// </summary>
		/// <param name="transaction">optional SQL Transaction</param>
		private void Delete(DbTransaction transaction = null)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_DELETE";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, CustomerInfoId))
			{
				if (transaction != null)
				{
					db.ExecuteNonQuery(dbCommand, transaction);
				}
				else
				{
					db.ExecuteNonQuery(dbCommand);
				}
			}
			CustomerInfoId = null;
		}

		#endregion

		#region SEARCH

		private static List<CustomerInfo> Search(Int32? customerInfoId = null, Int32? accountId = null, Int32? cityId = null, Int32? paymentTypeId = null,
		                                    String firstName = null, String middleName = null, String lastName = null, Int32? postIndex = null,
		                                    String postAddress = null, String phone = null, Int32? icq = null, String skype = null, String email = null,
		                                    DateTime? createdDate = null, DateTime? lastModifiedDate = null)
		{
			Database db = DatabaseFactory.CreateDatabase();
			const string sqlCommand = "[dbo].gspCustomerInfo_SEARCH";
			using (DbCommand dbCommand = db.GetStoredProcCommand(sqlCommand, customerInfoId, accountId, cityId, paymentTypeId, firstName, middleName, lastName, postIndex, postAddress, phone, icq, skype, email, createdDate, lastModifiedDate))
			{
				using (DataSet ds = db.ExecuteDataSet(dbCommand))
				{
					ds.Tables[0].TableName = TableName;
					return MapFrom(ds);
				}
			}
		}


		private static List<CustomerInfo> Search(CustomerInfo searchObject)
		{
			return Search(searchObject.CustomerInfoId, searchObject.AccountId, searchObject.CityId, searchObject.PaymentTypeId,
			              searchObject.FirstName, searchObject.MiddleName, searchObject.LastName, searchObject.PostIndex,
			              searchObject.PostAddress, searchObject.Phone, searchObject.Icq, searchObject.Skype, searchObject.Email,
			              searchObject.CreatedDate, searchObject.LastModifiedDate);
		}

		#endregion

		#endregion

		#endregion
	}
}